grammar HealthEvaluate;

main: FUN LBRACE NEWLINE* command NEWLINE* RBRACE EOF;                                         // 指标计算入口

command: (prog | NEWLINE )* ;

prog:   (compare (SEMI | NEWLINE))+
    |   (setArg  (SEMI | NEWLINE))+
    |   condition+
    |   calcu
    ;


condition: ifs LBRACE ifblock= command RBRACE (elif LBRACE command RBRACE)*?  (ELSE LBRACE elseblock = command RBRACE)?;

ifs: IF LPARENTHESE? compare RPARENTHESE?;
elif: ELIF LPARENTHESE? compare RPARENTHESE?;

setArg :'number'  id = ID '='  calcu                                                                                #numarg
       |'string'  id = ID '='  value = CHAR                                                                         #chararg
       |'boolean' id = ID '='  compare                                                                              #boolarg
       ;

compare: compare AND compare                                                                                        #and
       | compare OR compare                                                                                         #or
       | expr                                                                                                       #exre
       | BOOL                                                                                                       #bool
       ;

expr: fator operatorL = (EQ|NEQ|LT|LE|GT|GE) fator operatorR = (EQ|NEQ|LT|LE|GT|GE) fator                           #doubleSymbol
    | fator EQ fator                                                                                                #eq
    | fator NEQ fator                                                                                               #noteq
    | fator LT fator                                                                                                #lt
    | fator LE fator                                                                                                #le
    | fator GT fator                                                                                                #gt
    | fator GE fator                                                                                                #ge
    ;

fator: LPARENTHESE expr RPARENTHESE                             #fatorExpr
     | calcu                                                    #fatorParam
     | BOOL                                                     #fatorBool
     ;


calcu: LPARENTHESE calcu RPARENTHESE                            # parens
     | calcu opt=(MUL|DIV) calcu                                # mulAndDiv
     | calcu opt=(ADD|SUB) calcu                                # addAndSub
     | calcu LPARENTHESE calcu                                  # tandemLeft
     | calcu RPARENTHESE calcu                                  # tandemRight
     | PARAM                                                    # param
     | NUMBER                                                   # number
     | XN                                                       # xn
     | abs                                                      # calcuAbs
     ;

abs: ABS LPARENTHESE NUMBER RPARENTHESE                         # absNumber
     | ABS LPARENTHESE calcu RPARENTHESE                        # absCalcu
     ;



COMMENT : '/*' .*? '*/' '\n' -> skip ;
SL_COMMENT : '//' .*? '\n'-> skip  ;
WS : [ \t]+ -> skip ;                // 空白， 后面的->skip表示antlr4在分析语言的文本时，符合这个规则的词法将被无视
NEWLINE: '\r'? '\n' ;     // 换行符
EQ : NEWLINE? '==' NEWLINE?;
NEQ: NEWLINE? '!=' NEWLINE?;
LT : NEWLINE?'<' NEWLINE?;
LE : NEWLINE?'<=' NEWLINE?;
GT : NEWLINE?'>' NEWLINE?;
GE : NEWLINE?'>=' NEWLINE?;
AND : NEWLINE? '&&' NEWLINE?;
OR :  NEWLINE? '||' NEWLINE?;
MUL : '*' ;
DIV : '/' ;
ADD : '+' ;
SUB : '-' ;
IF: 'if';
ELIF: 'elif' |'elseif';
THEN: 'then';
ELSE: 'else';
SEMI:  ';';
COMMA:  ',';
DOT:   '.';
LBRACE:             '{';
RBRACE:             '}';
LPARENTHESE:             '(';
RPARENTHESE:             ')';
BOOL : 'true' | 'false' ;
NUMBER : '-'? [0-9]+('.'([0-9]+)?)? ;        // 数字
CHAR: '"' .*? '"';
fragment ID_LETTER : [a-z] | [A-Z] | '_' ;
fragment DIGIT : [0-9] ;
fragment LETTER :[0-9]| [a-z] | [A-Z] |'-' | '_' | '.';
fragment CHARTS: LETTER+ ;
ID : ID_LETTER (ID_LETTER | DIGIT)* ;
FUN: 'function()';
PARAM : '$$' DOT CHARTS;  //关联参数代号 #参数代号($$.arg1)
XN : '#xn' DOT CHARTS;  //性能指标代号 #参数代号(#xn1)
ABS: 'math.abs' | 'MATH.ABS' | 'Math.Abs';